/*******************************************************************************
 * Package: com.hngtrust.iir.user.controller
 * Type:    UserController
 * Date:    2021-3-15 17:15
 *
 * Copyright (c) 2021 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.hngtrust.iir.user.controller;

import cn.hutool.core.bean.BeanUtil;
import com.hngtrust.framework.bind.ResponseInfo;
import com.hngtrust.framework.id.service.MyIdGenerator;
import com.hngtrust.framework.page.PageResult;
import com.hngtrust.framework.page.service.PageService;
import com.hngtrust.framework.security.util.SecurityUtils;
import com.hngtrust.iir.base.controller.vo.OptLogReqVO;
import com.hngtrust.iir.base.service.LogService;
import com.hngtrust.iir.company.controller.vo.AiCompanyReqVO;
import com.hngtrust.iir.constant.Constant;
import com.hngtrust.iir.dto.ReqDTO;
import com.hngtrust.iir.user.controller.dto.EditTidingsPushReqVO;
import com.hngtrust.iir.user.controller.dto.EditUserReqVO;
import com.hngtrust.iir.user.controller.dto.GetValidatePicReqVO;
import com.hngtrust.iir.user.controller.dto.GetValidatePicRespVO;
import com.hngtrust.iir.user.dto.ListUserReqVO;
import com.hngtrust.iir.user.controller.dto.TidingsPushRespVO;
import com.hngtrust.iir.user.entity.Department;
import com.hngtrust.iir.user.entity.User;
import com.hngtrust.iir.user.service.DepartmentService;
import com.hngtrust.iir.user.service.UserService;
import com.hngtrust.iir.util.ListUtil;
import com.hngtrust.iir.util.RsaUtils;
import com.hngtrust.iir.util.VerifyCodeUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.security.PermitAll;
import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * 用户操作
 * @author Chentianyong
 * @date 2021-3-15 17:15
 */
@Slf4j
@Api(tags = "用户操作")
@RestController
@RequestMapping("/user")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private DepartmentService departmentService;
    
    @Autowired
    private LogService logService;
    
    /**
     * Redis 模板
     */
    @Autowired
    private RedisTemplate redisTemplate;
    
    /**
     * 分页服务
     */
    @Autowired
    private PageService pageService;
    
    /**
     * 主键生成器
     */
    @Autowired
    private MyIdGenerator myIdGenerator;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    //OA验证key
    @Value("${oa.login.public-key}")
    private String publicKey;
    
    /**
     * 用户列表
     */
    @ApiOperation(value = "用户列表", notes = "用户列表")
    @PostMapping("/list-user")
    public ResponseInfo<PageResult<User>> listUser(
            @ApiParam(value = "用户列表") @Valid @RequestBody ReqDTO<ListUserReqVO> req) {
        log.info("UserController.listUser start...");
    
        ListUserReqVO user = req.getContent();
        user.setStatus(Constant.DEFAULT_STATUS_NORMAL);
        PageResult<User> page = pageService.page(req.getPageParam(), () -> userService.queryUser(user));
    
        PageResult<User> pageResult = new PageResult<>();
        ListUtil<User> listUtil = BeanUtils.instantiateClass(ListUtil.class);
        listUtil.copyList(page,pageResult,User.class);
    
        return new ResponseInfo<PageResult<User>>(pageResult);
    }
    
    /**
     * 部门列表
     */
    @ApiOperation(value = "部门列表", notes = "部门列表")
    @PostMapping("/list-dept")
    public ResponseInfo<List<Department>> listDept(
            @ApiParam(value = "部门列表") @Valid @RequestBody Department req) {
        log.info("UserController.listDept start...");
        
        Department department = new Department();
        department.setStatus(Integer.valueOf(Constant.SUCCESS));
        //BeanUtils.copyProperties(req,user);
        List<Department> list = departmentService.queryList(department);
        
        ResponseInfo<List<Department>> data = new ResponseInfo<>();
        data.setData(list);
        return data;
    }
    
    @ApiOperation(value = "用户的推送方式")
    @PostMapping("/tidings-push")
    public ResponseInfo<TidingsPushRespVO> tidingsPush(@ApiParam(value = "推送方式") @Valid @RequestBody EditTidingsPushReqVO reqDTO){
        User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        User user = userService.queryById(loginUser.getId());
        TidingsPushRespVO vo =new TidingsPushRespVO();
        vo.setMsgModel(user.getMsgModel());
        vo.setId(loginUser.getId());
        vo.setEmail(user.getEmail());
        return new ResponseInfo<TidingsPushRespVO>(vo);
    }
    
    @ApiOperation(value = "修改用户的推送方式")
    @PostMapping("/update-tidings-push")
    public ResponseInfo<EditTidingsPushReqVO> updateTidingsPush(@ApiParam(value = "推送方式") @Valid @RequestBody EditTidingsPushReqVO vo){
        User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        loginUser.setEmail(vo.getEmail());
        loginUser.setMsgModel(vo.getMsgModel());
        userService.modifyById(loginUser);
        String s = vo.getMsgModel().substring(0,1);
        String wx = vo.getMsgModel().substring(1, 2);
        OptLogReqVO vo1 = new OptLogReqVO();
        vo1.setStatus(1);
        vo1.setOptModule(13);
        if (s.equals("0")){
            vo1.setOptType(15);
            vo1.setOptContent("禁用预警消息通知");
            logService.saveOptLog(vo1);
        }else {
            vo1.setOptType(16);
            vo1.setOptContent("启用预警消息通知");
            logService.saveOptLog(vo1);
        }
    
        if (wx.equals("0")){
            vo1.setOptType(15);
            vo1.setOptContent("禁用企业微信消息通知");
            logService.saveOptLog(vo1);
        }else {
            vo1.setOptType(16);
            vo1.setOptContent("启用企业微信消息通知");
            logService.saveOptLog(vo1);
        }
        return new ResponseInfo<>(vo);
    }
    
    
    /**
     * 取当前用户信息
     */
    @ApiOperation(value = "取当前用户信息", notes = "取当前用户信息")
    @PostMapping("/user-info")
    public ResponseInfo<User> userInfo(
            @ApiParam(value = "用户名称") @Valid @RequestBody AiCompanyReqVO req) {
        log.info("UserController.userInfo start...");
        
        User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        if(!loginUser.getUserCode().equals(req.getName())){
            loginUser = null;
        }
        
        return new ResponseInfo<User>(loginUser);
    }
    
    /**
     * 生成rsa密码
     */
    @ApiOperation(value = "生成rsa密码", notes = "生成rsa密码")
    @PostMapping("/key")
    @PermitAll
    public ResponseInfo<User> userKey(@RequestBody String req) {
        log.info("UserController.userKey start...");
        User user = new User();
        try{
            String pubKeyStr = RsaUtils.encryptByPubKey(req+"IIR", publicKey);
            user.setUserCode(req);
            user.setPassword(pubKeyStr);
        }catch (Exception e) {
            log.error("获取加密异常:{}", e);
            return null;
        }
        return new ResponseInfo<User>(user);
    }
    
    /**
     * 获取验证码图片
     */
    @ApiOperation(value = "获取验证码图片", notes = "获取验证码图片")
    @PostMapping("/get-validate-pic")
    @PermitAll
    public ResponseInfo<GetValidatePicRespVO> getValidatePic(@ApiParam(value = "本次请求的标识码，最好8位以上的唯一串", required = true) @Valid @RequestBody GetValidatePicReqVO reqVO) {
        log.info("UserController.getValidatePic start...");
        
        // 图片验证码KEY
        StringBuilder picCode = new StringBuilder();
        picCode.append("PVCODE");
        picCode.append('_');
        picCode.append(reqVO.getReqTag());
        String pritureKey = picCode.toString();
        
        String pictureValue = VerifyCodeUtils.generateVerifyCode(VerifyCodeUtils.VERIFY_NUM);
        String pciData = "";
        try {
            ByteArrayOutputStream picStream = new ByteArrayOutputStream();
            VerifyCodeUtils.outputVerifyImage(picStream, pictureValue);
            pciData = Base64.encodeBase64String(picStream.toByteArray());
        }
        catch (IOException e) {
            log.error("获取图片验证码出错:", e);
            return new ResponseInfo<>(Constant.FAIL, "获取图片验证码出错");
        }
        redisTemplate.opsForValue().set(pritureKey, pictureValue);
        
        GetValidatePicRespVO resp = new GetValidatePicRespVO();
        resp.setPicData(pciData);
        ResponseInfo<GetValidatePicRespVO> data = new ResponseInfo<>();
        data.setData(resp);
        return data;
    }
    
    /**
     * 用户新增
     */
    @ApiOperation(value = "用户新增", notes = "用户新增")
    @PostMapping("/add-user")
    public ResponseInfo<Object> addUser(
            @ApiParam(value = "用户新增") @Valid @RequestBody EditUserReqVO req) {
        log.info("UserController.addUser start...");
        
        User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        User user = new User();
        user.setUserCode(req.getUserCode());
        user.setStatus(0);
        //检查用户号，不能重复
        List<User> list = userService.queryList(user);
        if(!list.isEmpty()){
            return new ResponseInfo<>(Constant.FAIL, "用户编号不能重复");
        }
    
        user.setUserType(1);//系统新增用户
        BeanUtil.copyProperties(req, user);
        if(!StringUtils.isEmpty(req.getPassword())){
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        }
        user.setId(myIdGenerator.nextId());
        user.setCreateTime(new Date());
        user.setCreateUserId(loginUser.getId());
        user.setUpdateTime(new Date());
        user.setUpdateUserId(loginUser.getId());
        userService.add(user);
        
        return new ResponseInfo<>();
    }
    
    /**
     * 用户修改
     */
    @ApiOperation(value = "用户修改", notes = "用户修改")
    @PostMapping("/edit-user")
    public ResponseInfo<Object> editUser(
            @ApiParam(value = "用户修改") @Valid @RequestBody EditUserReqVO req) {
        log.info("UserController.editUser start...");
        
        User loginUser = (User) SecurityUtils.getLoginUser().getAdditionalInfo();
        User user = new User();
        if(!StringUtils.isEmpty(req.getUserCode())){
            user.setUserCode(req.getUserCode());
            //检查用户号，不能重复
            List<User> userList = userService.queryList(user);
            if(!userList.isEmpty()){
                if(userList.size() > 1){
                    return new ResponseInfo<>(Constant.FAIL, "用户编号不能重复");
                }
                User oldUser = userList.get(0);
                if(!oldUser.getId().equals(req.getId())){
                    return new ResponseInfo<>(Constant.FAIL, "用户编号不能重复");
                }
            }
        }
        
        BeanUtil.copyProperties(req, user);
        user.setUpdateTime(new Date());
        user.setUpdateUserId(loginUser.getId());
        if(!StringUtils.isEmpty(req.getPassword())){
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        }
        
        userService.modifyById(user);
        
        return new ResponseInfo<>();
    }
    
    /**
     * 用户删除
     */
    @ApiOperation(value = "用户删除", notes = "用户删除")
    @PostMapping("/del-user")
    public ResponseInfo<Object> delUser(
            @ApiParam(value = "用户删除") @Valid @RequestBody User req) {
        log.info("UserController.delUser start...");
        
        User user = new User();
        user.setId(req.getId());
        user.setStatus(1); //删除
        userService.modifyById(user);
        
        return new ResponseInfo<>();
    }
    
}
